home *** CD-ROM | disk | FTP | other *** search
- #if !defined( __DOS_H )
- #include <Dos.h>
- #endif // __DOS_H
-
- #if !defined( __COMSTREAM_H )
- #include "Comstream.h"
- #endif // __COMSTREAM_H
-
- #if !defined( __TIMER_H )
- #include "Timer.h"
- #endif // __TIMER_H
-
- #define TESTPORTBIT(x,y) (inportb(x) & y)
-
- #define IER 1
- #define IIR 2
- #define LCR 3
- #define LSR 5
- #define MSR 6
-
- #define MODEMFAIL 0
- #define XMTEMPTY 2
- #define READFULL 4
- #define LINEFAIL 6
-
- #define RXRDY 1
- #define TBE 32
- #define TXE 64
-
- #define RTS 2
- #define GP01 4
- #define GP02 8
- #define LOOPBACK 16
-
- #define CTS 16
-
- #define DLAB 128
-
- ComDef::ComDef( int n )
- {
- if( n >= 0 && n < 4 )
- {
- unsigned far *pPort = (unsigned far *) MK_FP( 0, 0x400 );
- portAddr = pPort[n];
- }
- else
- portAddr = 0;
-
- if( portAddr != 0 )
- {
- irqAddr = ( n & 1 ) ? 0x0B : 0x0C;
- picMask = ( n & 1 ) ? 0x08 : 0x10;
- oldhandler = getvect( irqAddr );
- }
- else
- {
- irqAddr = picMask = 0;
- oldhandler = 0;
- }
- owner = 0;
- }
-
- ComDef::~ComDef()
- {
- clrCombuf();
- }
-
- void ComDef::setParams( int aPort, int aIRQ, int aMask )
- {
- if( owner != 0 ) return;
-
- if( oldhandler && irqAddr )
- setvect( irqAddr, oldhandler );
- oldhandler = 0;
-
- portAddr = aPort;
- irqAddr = aIRQ;
- picMask = aMask;
- oldhandler = getvect( irqAddr );
- }
-
- int ComDef::setCombuf( combuf *cb )
- {
- void interrupt far (*handler)(...);
-
- if( owner != 0 ) return 0;
-
- if( irqAddr == 0x0B )
- handler = combuf::handler0x0B;
- else if( irqAddr == 0x0C )
- handler = combuf::handler0x0C;
- else
- return 0;
-
- owner = cb;
- outportb( portAddr+MCR, 0 );
- outportb( portAddr+IER, 0 );
- outportb( portAddr+LCR, inportb(portAddr+LCR) & 0x3F );
- for( int i = 0; i < 7; i++ )
- inportb( portAddr+i );
- setvect( irqAddr, handler );
- outportb( 0x21, (inportb(0x21) & ~picMask) );
- outportb( portAddr+MCR, GP02 );
- outportb( portAddr+IER, 0x0F );
- return 1;
- }
-
- void ComDef::clrCombuf()
- {
- if( owner == 0 ) return;
- if( irqAddr != 0x0B && irqAddr != 0x0C )
- return;
- outportb( 0x21, (inportb(0x21) | picMask) );
- outportb( portAddr+MCR, 0 );
- outportb( portAddr+IER, 0 );
- setvect( irqAddr, oldhandler );
- owner = 0;
- }
-
- ComDef combuf::def[] = { 0, 1, 2, 3 };
-
- void interrupt far combuf::handler0x0B(...)
- {
- combuf *owner;
- int i, port, cause, data;
-
- for( i = 0; i < NUMBEROFPORTS; i++ )
- if( (owner = combuf::def[i].owner) != 0 && combuf::def[i].irqAddr == 0x0B )
- {
- port = combuf::def[i].portAddr;
- cause = inportb( port+IIR ) & 0x0F;
- if( (cause & 1) == 0 )
- {
- if( cause == READFULL ) data = inportb( port );
- else if( cause == LINEFAIL ) data = inportb( port+LSR );
- else if( cause == MODEMFAIL ) data = inportb( port+MSR );
- outportb( 0x20, 0x20 );
- owner->handleIRQ( port, cause, data );
- return;
- }
- }
- outportb( 0x20, 0x20 );
- }
-
-
- void interrupt far combuf::handler0x0C(...)
- {
- combuf *owner;
- int i, port, cause, data;
-
- for( i = 0; i < NUMBEROFPORTS; i++ )
- if( (owner = combuf::def[i].owner) != 0 && combuf::def[i].irqAddr == 0x0C )
- {
- port = combuf::def[i].portAddr;
- cause = inportb( port+IIR ) & 0x0F;
- if( (cause & 1) == 0 )
- {
- if( cause == READFULL ) data = inportb( port );
- else if( cause == LINEFAIL ) data = inportb( port+LSR );
- else if( cause == MODEMFAIL ) data = inportb( port+MSR );
- outportb( 0x20, 0x20 );
- owner->handleIRQ( port, cause, data );
- return;
- }
- }
- outportb( 0x20, 0x20 );
- }
-
- void combuf::handleIRQ( int port, int cause, int data )
- {
- if( cause == READFULL )
- insertc( data );
- else if( cause == XMTEMPTY )
- {
- int ch = extractc();
- if( ch != EOF )
- {
- if( ibdelay_ != 0 || (ch == '\r' && ildelay_ != 0) )
- {
- long l = (ch == '\r' && ildelay_ != 0) ? ildelay_ : ibdelay_;
- int n = inportb( 0x21 );
- outportb( 0x21, n | 0x18 );
- enable();
- Timer timer;
- while( timer.elapsed() < l );
- disable();
- outportb( 0x21, n );
- }
- outportb( port, ch );
- }
- }
- else if( cause == LINEFAIL )
- errFlags |= ( data & (OR | FE | PE | BI) );
- }
-
- combuf::combuf( char *b, int inlen, int outlen ) : streambuf( b, inlen+outlen )
- {
- inSize = inlen;
- errFlags = 0;
- options = 0;
- offs_ = EOF;
- setTimeout( 300 );
- setInterCharDelay( 0 );
- setInterLineDelay( 0 );
- }
-
- combuf::combuf()
- {
- inSize = 0;
- errFlags = 0;
- options = 0;
- offs_ = EOF;
- setTimeout( 300 );
- setInterCharDelay( 0 );
- setInterLineDelay( 0 );
- }
-
- combuf::~combuf()
- {
- setPort();
- }
-
- streambuf *combuf::setbuf( signed char *b, int len )
- {
- streambuf::setbuf( b, len );
- inSize = len/2;
- return this;
- }
-
- combuf *combuf::setbuf( char *b, int inlen, int outlen )
- {
- streambuf::setbuf( b, inlen+outlen );
- inSize = inlen;
- return this;
- }
-
- int combuf::underflow()
- {
- Timer timer;
-
- if( offs_ == EOF ) return EOF;
-
- if( in_avail() == 0 )
- {
- while( timer.elapsed() < timeout_ && in_avail() == 0 );
- if( in_avail() == 0 )
- {
- errFlags |= TIMEOUT;
- return EOF;
- }
- }
- return (unsigned char) *(gptr());
- }
-
- int combuf::do_sputn( const char *b, int len )
- {
- Timer timer;
- long l;
- int i, port, n;
-
- if( offs_ == EOF || base() == 0 || len <= 0)
- return 0;
-
- if( pptr() == 0 )
- {
- port = def[offs_].portAddr;
- if( (options & HW_HANDSHAKE) != 0 )
- assertToPort( MCR, RTS );
- if( ibdelay_ != 0 || (*b == '\r' && ildelay_ != 0) )
- {
- l = (*b == '\r' && ildelay_ != 0) ? ildelay_ : ibdelay_;
- timer.start();
- while( timer.elapsed() < l );
- }
-
- timer.start();
- while( TESTPORTBIT(port+LSR,TBE) == 0 &&
- ( (options & HW_HANDSHAKE) == 0 || TESTPORTBIT(port+MSR,CTS) != 0 ) )
- if( timer.elapsed() >= timeout_ )
- {
- errFlags |= TIMEOUT;
- return 0;
- }
-
- if( len == 1 )
- {
- outportb( port, *b );
- return 1;
- }
-
- n = blen()-inSize;
- setp( base()+inSize, ebuf() );
- if( n >= len-1 )
- {
- memcpy( pptr(), b+1, len-1 );
- pbump( len-1 );
- outportb( port, *b );
- return len;
- }
-
- memcpy( pptr(), b+1, n );
- pbump( n );
- outportb( port, *b );
- b += (n+1);
- for( i = n+1; i < len && sputc(*b++) != EOF; i++ )
- i++;
- return i;
- }
- else
- return streambuf::do_sputn( b, len );
- }
-
- int combuf::overflow( int c )
- {
- char b = c;
- return do_sputn( &b, 1 );
- }
-
- void combuf::setBaud( long baud )
- {
- if( offs_ == EOF || baud < 50 || baud > 115200L )
- return;
- unsigned u = (unsigned) ( 115200L / baud );
- assertToPort( LCR, DLAB );
- outportb( def[offs_].portAddr, (u & 0xFF) );
- outportb( def[offs_].portAddr+1, ((u >> 8) & 0xFF) );
- unassertToPort( LCR, DLAB );
- }
-
- void combuf::setParity( int parity )
- {
- int i;
-
- if( offs_ == EOF ) return;
- else if( parity == NO_PARITY ) i = 0;
- else if( parity == ODD_PARITY ) i = 0x08;
- else if( parity == EVEN_PARITY ) i = 0x18;
- else return;
- outportb( def[offs_].portAddr+LCR, (inportb(def[offs_].portAddr+LCR) & 0xC7) | i );
- }
-
- void combuf::setBits( int bits )
- {
- if( offs_ == EOF || bits < 6 || bits > 8 ) return;
- bits -= 5;
- outportb( def[offs_].portAddr+LCR, (inportb(def[offs_].portAddr+LCR) & 0xFC) | bits );
- }
-
- void combuf::setStopBits( int bits )
- {
- if( offs_ == EOF || bits < 1 || bits > 2 ) return;
- bits = (bits-1)*4;
- outportb( def[offs_].portAddr+LCR, (inportb(def[offs_].portAddr+LCR) & 0xFB) | bits );
- }
-
- void combuf::setParams( CommProtocol& p )
- {
- if( offs_ == EOF ) return;
- if( p.baud < 50L || p.baud > 115200L ) return;
- if( p.parity < NO_PARITY || p.parity > EVEN_PARITY ) return;
- if( p.bits < 6 || p.bits > 8 ) return;
- if( p.stopBits != 1 && p.stopBits != 2 ) return;
-
- setBaud( p.baud );
- setParity( p.parity );
- setBits( p.bits );
- setStopBits( p.stopBits );
- }
-
- void combuf::setTimeout( unsigned long l )
- {
- timeout_ = timeToTicks( l );
- }
-
- void combuf::setInterCharDelay( unsigned long l )
- {
- ibdelay_ = timeToTicks( l );
- }
-
- void combuf::setInterLineDelay( unsigned long l )
- {
- ildelay_ = timeToTicks( l );
- }
-
- void combuf::setPort( int p )
- {
- if( offs_ != EOF )
- def[offs_].clrCombuf();
- if( p < 0 || p > 3 || blen() == 0 )
- p = EOF;
- offs_ = p;
- if( offs_ != EOF )
- {
- for( int i = 0; i < NUMBEROFPORTS; i++ )
- {
- if( i == p ) continue;
- if( def[i].owner != 0 )
- if( def[i].portAddr == def[p].portAddr ||
- def[i].irqAddr == def[p].irqAddr ||
- def[i].picMask == def[p].picMask )
- break;
- }
- if( i < NUMBEROFPORTS )
- offs_ = EOF;
-
- else if( def[offs_].setCombuf( this ) == 0 )
- offs_ = EOF;
- else
- {
- setg( base(), base(), base() );
- setp( 0, 0 );
- }
- }
- errFlags = 0;
- }
-
- int combuf::extractc()
- {
- Timer timer;
- int n, ch;
-
- if( (n = out_waiting()) != 0 )
- {
- char *pb = pbase();
- ch = *pb;
- if( n > 1 )
- {
- pb++;
- setp( pb, epptr() );
- pbump(n-1);
- }
- else
- setp( 0, 0 );
- }
- else
- {
- setp( 0, 0 );
- ch = EOF;
- }
- return ch;
- }
-
- int combuf::insertc( int c )
- {
- if( egptr() < base()+inSize )
- {
- *(egptr()) = c;
- setg( base(), gptr(), egptr()+1 );
- }
- else if( gptr() > base() )
- {
- int len = (int)(egptr() - gptr());
- memmove( base(), gptr(), len );
- *(base()+len) = c;
- setg( base(), base(), base()+len+1 );
- }
- else
- {
- errFlags |= OR;
- return EOF;
- }
- return c;
- }
-
- unsigned long combuf::timeToTicks( unsigned long l )
- {
- return l * 182L / 1000L;
- }
-
- void combuf::assertToPort( int o, int mask )
- {
- outportb( def[offs_].portAddr+o, (inportb(def[offs_].portAddr+o) | mask) );
- }
-
- void combuf::unassertToPort( int o, int mask )
- {
- outportb( def[offs_].portAddr+o, (inportb(def[offs_].portAddr+o) & ~mask) );
- }
-
- comstream::comstream() : buf()
- {
- ios::init(&buf);
- }
-
- comstream::comstream( char *cbuf, int isz, int osz ) :
- buf( cbuf, isz, osz )
- {
- ios::init(&buf);
- }
-
- comstream::~comstream()
- {
- }
-
- void comstream::open( int aPort )
- {
- if( buf.offs_ != EOF )
- clear(ios::failbit);
- else
- {
- buf.setPort(aPort);
- if( buf.offs_ != EOF )
- {
- clear(ios::goodbit);
- buf.assertDTR();
- }
- else
- clear(ios::badbit);
- }
- }
-
- void comstream::close()
- {
- buf.setPort();
- if( buf.offs_ == EOF )
- clear(ios::goodbit);
- else
- setstate(ios::failbit);
- }
-
-
- static comstream& sbd( comstream& o, long b )
- {
- o.rdbuf()->setBaud(b);
- return o;
- }
-
- ComManipLong baud( long b )
- {
- return ComManipLong( sbd, b );
- }
-
- static comstream& sbit( comstream& o, int b )
- {
- o.rdbuf()->setBits(b);
- return o;
- }
-
- ComManipInt bits( int b )
- {
- return ComManipInt( sbit, b );
- }
-
- static comstream& spty( comstream& o, int b )
- {
- o.rdbuf()->setParity(b);
- return o;
- }
-
- ComManipInt parity( int b )
- {
- return ComManipInt( spty, b );
- }
-
- static comstream& ssbit( comstream& o, int b )
- {
- o.rdbuf()->setStopBits(b);
- return o;
- }
-
- ComManipInt stopbits( int b )
- {
- return ComManipInt( ssbit, b );
- }
-
- static comstream& sto( comstream& o, long t )
- {
- o.rdbuf()->setTimeout(t);
- return o;
- }
-
- ComManipLong timeout( long t )
- {
- return ComManipLong( sto, t );
- }
-
- static comstream& icd( comstream& o, int d )
- {
- o.rdbuf()->setInterCharDelay( d );
- return o;
- }
-
- ComManipInt intercharDelay( int d )
- {
- return ComManipInt( icd, d );
- }
-
- static comstream& ild( comstream& o, int d )
- {
- o.rdbuf()->setInterLineDelay( d );
- return o;
- }
-
- ComManipInt interlineDelay( int d )
- {
- return ComManipInt( ild, d );
- }
-